<template>
  <view class="tn-checkbox" :class="[checkboxClass]" :style="checkboxStyle" @tap.stop="handleSelect">
    <!-- 选择框 -->
    <view class="tn-checkbox__select" :class="[selectClass]" :style="selectStyle">
      <view v-if="selectState" class="tn-checkbox__select--icon">
        <tn-icon icon="success"></tn-icon>
      </view>
    </view>
    <!-- label -->
    <view class="tn-checkbox__label" @tap.stop="handlelabelClick">
      <slot></slot>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { checkboxProps, checkboxEmits, checkboxGroupKey } from '../../../types/tn-checkbox'
import { inject, computed, CSSProperties, watch } from 'vue'
import { ColorInfo, TuniaoSize, TuniaoSizes } from '../../../types/tuniao-ui'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { handleValueWithUnit } from '../../../utils'
import TnIcon from '../../tn-icon/src/Icon.vue'
import { UPDATE_MODEL_EVENT } from '../../../constants'

const props = defineProps(checkboxProps)
const emits = defineEmits(checkboxEmits)

// checkboxGroup
const checkboxGroupContext = inject(checkboxGroupKey, undefined)

const { splitColorInfo } = useComponentColor()

// 选中状态
const selectState = computed<boolean>(() => {
  return checkboxGroupContext?.activeName.includes(props.name) || props?.modelValue || false
})
watch(() => selectState.value, (val: boolean) => {
  emits('change', val)
})

// 禁用状态
const disabled = computed<boolean>(() => {
  return props?.disabled !== undefined ? (props?.disabled || false) : (checkboxGroupContext?.disabled || false)
})
// 标签禁止点击状态
const disabledLabel = computed<boolean>(() => {
  return props?.disabledLabel !== undefined ? (props?.disabledLabel || false) : (checkboxGroupContext?.disabledLabel || false)
})
// 选中时的颜色
const activeColor = computed<ColorInfo>(() => {
  return splitColorInfo('bg', props?.activeColor || checkboxGroupContext?.activeColor || '')
})
// 组件尺寸
const size = computed<string>(() => {
  const size = props?.size || checkboxGroupContext?.size || ''
  if (TuniaoSizes.includes(size as TuniaoSize)) {
    return size as TuniaoSize
  }
  return handleValueWithUnit(size)
})
// checkbox宽度
const width = computed<string>(() => {
  return handleValueWithUnit(props?.width || checkboxGroupContext?.width || '')
})

// checkbox样式
const checkboxStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (width.value) {
    style.width = width.value
  }
  if (size.value && !TuniaoSizes.includes(size.value as TuniaoSize)) {
    style.fontSize = size.value
    style.height = `calc(${size.value} + 20rpx)`
  }
  return style
})
// 选择框样式
const selectStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (selectState.value && activeColor.value.type === 'style') style.backgroundColor = activeColor.value.value
  if (size.value && !TuniaoSizes.includes(size.value as TuniaoSize)) {
    style.width = `calc(${size.value} - 10rpx)`
    style.height = style.width
  }
  return style
})

// checkbox对应class
const checkboxClass = computed<string>(() => {
  let clazz: string[] = []
  if (disabled.value) {
    clazz.push('disabled')
  }
  if (selectState.value) {
    clazz.push('select')
  }
  if (size.value && TuniaoSizes.includes(size.value as TuniaoSize)) {
    clazz.push(`tn-checkbox--${size.value}`)
  }
  return clazz.join(' ')
})
// 选择框对应的类
const selectClass = computed<string>(() => {
  let clazz: string[] = []
  if (selectState.value && activeColor.value.type === 'class') {
    clazz.push(activeColor.value.value)
  }
  return clazz.join(' ')
})

// 选中操作
const handleSelect = () => {
  if (disabled.value) return
  emits(UPDATE_MODEL_EVENT, !props.modelValue)
  checkboxGroupContext?.changeEvent(props.name)
}
// 标签点击事件
const handlelabelClick = (event: any) => {
  if (!disabledLabel.value) {
    handleSelect()
  }
}
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>
@import '../../../theme.scss';

.tn-checkbox {
  position: relative;
  width: auto;
  display: flex;
  padding: 10rpx 14rpx;
  flex-direction: row;
  align-items: center;
  justify-content: flex-start;
  font-size: $tn-font-size;
  height: 44rpx;

  &__select {
    position: relative;
    width: 24rpx;
    height: 24rpx;
    //border-radius: 4rpx;
    border: 1rpx solid #AAAAAA;
    margin-right: 10rpx;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.25s ease-out;
    // 20230424 改为圆角
    border-radius: 50%!important;
    &--icon {
      color: #FFFFFF;
      transform-origin: center center;
      transform: scale(0.7);
      line-height: 1;
    }
  }
  &__label {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
  }

  &.select {
    .tn-checkbox__select {
      border: none;
      background-color: $tn-main-color;
    }
  }

  &.disabled {
    opacity: 0.3;
  }

  /* 内置尺寸 start */
  &--sm {
    height: 40rpx;
    font-size: 24rpx;
    .tn-checkbox__select {
      width: 20rpx;
      height: 20rpx;
    }
  }
  &--lg {
    height: 48rpx;
    font-size: 34rpx;
    .tn-checkbox__select {
      width: 28rpx;
      height: 28rpx;
    }
  }
  &--xl {
    height: 52rpx;
    font-size: 38rpx;
    .tn-checkbox__select {
      width: 32rpx;
      height: 32rpx;
    }
  }
  /* 内置尺寸 end */
}
</style>
